package cn.slipi.pan.common.util;

import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.AlgorithmParameters;
import java.security.Key;
import java.security.Security;

/**
 * Description: AES加密解密方法
 */
@Slf4j
public class AESUtil {

    //算法名
    public static final String KEY_ALGORITHM = "AES";
    public static final String CIPHER_ALGORITHM = "AES/CBC/PKCS7Padding";

    //生成密钥
    private static byte[] generateKey(String aesKey) {
        Security.addProvider(new BouncyCastleProvider());
        return aesKey.getBytes();
    }


    //生成iv

    private static AlgorithmParameters generateIV(String ivVal) throws Exception {
        byte[] iv = ivVal.getBytes();
        AlgorithmParameters params = AlgorithmParameters.getInstance(KEY_ALGORITHM);
        params.init(new IvParameterSpec(iv));
        return params;
    }


    //转化成JAVA的密钥格式
    private static Key convertToKey(byte[] keyBytes) {
        return new SecretKeySpec(keyBytes, KEY_ALGORITHM);
    }


    //加密

    public static String encrypt(String plainText, String aesKey, String ivVal) throws Exception {
        if (StrUtil.isEmpty(plainText)) {
            return null;
        }
        byte[] data = plainText.getBytes(StandardCharsets.UTF_8);
        AlgorithmParameters iv = generateIV(ivVal);
        byte[] keyBytes = generateKey(aesKey);
        //转化为密钥
        Key key = convertToKey(keyBytes);
        Security.addProvider(new BouncyCastleProvider());
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        //设置为加密模式
        cipher.init(Cipher.ENCRYPT_MODE, key, iv);
        byte[] encryptData = cipher.doFinal(data);
        return ByteFormat.bytesToHexString(encryptData);
    }


    //解密
    public static String decrypt(String encryptedStr, String aesKey, String ivVal) throws Exception {
        byte[] encryptedData = ByteFormat.hexToBytes(encryptedStr);
        byte[] keyBytes = generateKey(aesKey);
        Key key = convertToKey(keyBytes);
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        AlgorithmParameters iv = generateIV(ivVal);
        //设置为解密模式
        cipher.init(Cipher.DECRYPT_MODE, key, iv);
        byte[] decryptData = cipher.doFinal(encryptedData);
        return new String(decryptData);
    }

}
